/* Copyright 2008 Bas van den Berg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string>

#include "yaffut.h"
#include "myassert.h"
#include "TestConnection.h"
#include "Global.h"
#include "Logger.h"
#include "Utils.h"

#include "MudPlayer.h"
#include "SessionManager.h"
#include "SqliteDatabase.h"
#include "TaskQueue.h"
#include "MudServer.h"

using namespace std;
using namespace Chronos;


bool stop = false;


struct CmdRecord {
    unsigned int time;
    const char* cmd;
};

struct CmdRecord recording[] = {
     {41, "north"}
    ,{46, "west"}
    ,{57, "get all"}
    ,{226, "help"}
    ,{254, "inv"}
    ,{260, 0}
};

class TestPlayerTask : public Task {
public:
    TestPlayerTask(bool* stop_, TestConnection& c_) : stopLoop(stop_), times(0), connection(c_), cmdIndex(0) {}
    virtual unsigned int run() {
        times++;
        connection.setOutput("");

        CmdRecord* rec = &recording[cmdIndex];    
        if (times == rec->time) {
            if (rec->cmd == 0) {
                *stopLoop = true;
                return 0;
            }
            connection.setOutput(rec->cmd);
            cmdIndex++;
        }
        return 1;
    }
private:
    bool* stopLoop;
    unsigned int times;
    TestConnection& connection;
    int cmdIndex;
};


struct SystemTest {
	SystemTest()
        : database(SqliteDatabase::createDummy("../database.sql"))
        , server(6666, database)
        , connectionClosed(false)
		, connection(new TestConnection(&connectionClosed))
        , testTask(new TestPlayerTask(&stop, *connection))
    {
        MudPlayer::create(*database, "bas", "pass");
        Logger::level = ERROR;
        connection->setOutput("");
    }
    SqliteDatabase* database;
    MudServer server;
    bool connectionClosed;
	TestConnection* connection;
    TestPlayerTask* testTask;
};


TEST(SystemTest, testTaskShouldStopServer) {
    Global<TaskQueue>()->addTask(testTask, 1);
    Global<SessionManager>()->addPlayer("bas", connection);
    while (!stop) { // copied from MudServer main loop
        Utils::nextPulse();
        Global<TaskQueue>()->runNextTime();
        Global<SessionManager>()->handlePulse();
    }
}

